// 操作变量共享会有问题的售票系统

#include <iostream>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <string>
#include <cstdio>
#include <mutex>

using std::cin;
using std::cout;
using std::endl;
using std::to_string;
using std::string;

const int Num = 5; // 线程个数
int ticket = 1000;  // 临界资源、共享资源

class ThreadData
{
public:
    ThreadData(string name,pthread_mutex_t* pmutex) : _name(name),_pmutex(pmutex)
    {
    }
    ~ThreadData()
    {
    }

public:
    string _name;
    pthread_mutex_t* _pmutex;
};

void *Routine(void *arg)
{
    pthread_detach(pthread_self()); // 线程分离,主线程就不用去等待子(新)线程的退出。当主线程退出时，也不会去回收子线程。
    ThreadData *td = (ThreadData *)arg;
    cout << "i am " << td->_name << endl;
    return nullptr;
}

void* getTickets(void* arg)
{
    pthread_detach(pthread_self());
    ThreadData* td=(ThreadData*)arg;
    pthread_mutex_lock(td->_pmutex);
    while(ticket>0)
    {
        usleep(10000);//先睡再--：先等待一会，此时该线程认为ticket仍然是>0的。
                      //如果是先--再睡的话，此线程--了，但其他线程是可以发现ticket已经--了.就不会触发线程不安全的问题
                      //所以就要加锁，每个进程只有一把锁
        ticket--;
        cout<<"i am "<<td->_name<<" : now ticket is "<<ticket<<endl;
    }
    cout<<ticket<<": quit"<<endl;    
    pthread_mutex_unlock(td->_pmutex);
    pthread_exit((void*)666);
}




int main()
{
    pthread_mutex_t mutex;//每个进程只能有一把锁，多个线程共享一把锁。这里是在main里创了一把锁，线程池里的也是一把锁成员变量，都是被线程共享的一把锁。
    pthread_mutex_init(&mutex, NULL);
    pthread_t tids[Num];
    for (int i = 0; i < Num; i++)
    {
        string name = "thread ";
        name += to_string(i);
        ThreadData *td = new ThreadData(name,&mutex);
        pthread_create(&tids[i], nullptr, getTickets, td); // 线程创建
        
        // sleep(1);
    }
    while(1);
  
     pthread_mutex_destroy(&mutex);
    return 0;
}


